package com.miyu.client1.service.magic.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.miyu.client1.dao.book.bookChapterDao;
import com.miyu.client1.dao.book.bookDao;
import com.miyu.client1.dao.book.bookMagicDao;
import com.miyu.client1.pojo.book.BookChapter;
import com.miyu.client1.pojo.book.BookListInfo;
import com.miyu.client1.pojo.book.BookRule;
import com.miyu.client1.service.book.bookService;
import com.miyu.client1.service.magic.BookMagicService;
import com.miyu.client1.utils.bookUtils.JXPageRuleThread;
import com.miyu.client1.utils.bookUtils.BookCommutils;
import com.miyu.client1.utils.bookUtils.saveThead;
import com.miyu.client1.utils.ehcache.EhcacheUtil;
import com.miyu.client1.utils.redis.redisUtils.util.RedisListUtil;
import com.miyu.client1.utils.redis.redisUtils.util.RedisValUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.model.HttpRequestBody;
import us.codecraft.webmagic.utils.HttpConstant;

import javax.annotation.Resource;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;


@Service
public class BookMagicServiceImpl implements BookMagicService {


    @Autowired
    private bookService bookService;

    @Resource
    private bookMagicDao dao;
    @Resource
    private bookDao bookDao;

    @Resource
    private bookChapterDao bookChapterDao;

    @Override
    public JSONArray searchBook(JSONObject param) {

        List<BookRule> all = bookDao.queryBookRule();
        for (BookRule bookRule :all) {
            Request request = new Request();
            String startUrl="";
            //传参方式
            if (bookRule.getSysMethod().equals("POST")){
                request= new Request(bookRule.getRuleSearchUrl());
               // request.setUrl(bookRule.getRuleSearchUrl());
                request.setMethod(HttpConstant.Method.POST);
                Map<String,Object> params=new HashMap<>();
                //  params.put("type","undefined");
                params.put("keyword",param.get("search"));
                request.setRequestBody(HttpRequestBody.form(params,"utf-8"));
            }else {
                 startUrl=bookRule.getRuleSearchUrl()+param.get("search");
                 request.setUrl(startUrl);
            }
            //  JSONObject  bookRule = new JSONObject();
            request.putExtra("book","search");
            request.putExtra("state","main");
            request.putExtra("bookRule",JSONObject.toJSON(bookRule));
            BookMagicCommon.bookSearch(request);

        }

        //缓存取数据
        JSONArray jsonArray= JSONArray.parseArray(JSONObject.toJSONString(EhcacheUtil.getInstance().get("bookEhcache","bookCache")));

        //移除缓存
        EhcacheUtil.getInstance().remove("bookEhcache", "bookCache");
        //取出数据库中已存数据 赛选过滤 后期同步到缓存 优化性能
        JSONObject jo = dao.getData();

        for (int i = 0; i <jsonArray.size() ; i++) {
            JSONObject s = (JSONObject) jsonArray.get(i);
            if(jo.containsKey(s.getString("bookAuthor")+"@@"+s.getString("bookName"))){
                BookListInfo bi = (BookListInfo) jo.get(s.getString("bookAuthor")+"@@"+s.getString("bookName"));
                s.put("bookId",bi.getBookId());
            }
        }

  /*      //多线程下调用保存 不占查询时间
        String type = "search";
        ExecutorService exec = Executors.newCachedThreadPool();//工头
        exec.submit(new saveSearchTask(jsonArray,type));*/
        return jsonArray;
    }

    @Override
    public JSONObject saveBookListInfo(JSONArray bookListInfo) {
//        System.out.println(bookListInfo.getBookAuthor());
//        System.out.println(bookListInfo.getBookCover());
//        System.out.println(bookListInfo.getBookDuce());
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>多线程进入");
        return null;
    }

    /**
     * 数据明细页面数据 解析返回数据详情 章节列表
     * @param param
     * @return
     */
    @Override
    public JSONObject queryDetailBookList(JSONObject param) {
      //  BookListInfo bookListInfo = dao.findById("bookId").orElse(null);
        BookRule bookRule = bookDao.findById(param.getString("bookRuleSource")).orElse(null);
        Request request = new Request();
        request.putExtra("book","bookDetailList");
        request.putExtra("state","main");
        request.putExtra("bookRule", JSONObject.parse(JSONObject.toJSONString(bookRule)));
        request.putExtra("bookListInfo", param);
        request.setUrl(param.getString("ruleSearchNoteUrl"));
        request.setCharset("gbk");
        BookMagicCommon.bookSearch(request);
        //加入缓存暂时引入缓存+数据库保存
        //缓存取数据
        JSONArray jsonArray= JSONArray.parseArray(JSONObject.toJSONString(EhcacheUtil.getInstance().get("bookEhcache","detail")));
        JSONObject headTitleInfo = JSONObject.parseObject(JSONObject.toJSONString(EhcacheUtil.getInstance().get("bookEhcache","headTitleInfo")));
        //移除缓存
        EhcacheUtil.getInstance().remove("bookEhcache", "detail");
        EhcacheUtil.getInstance().remove("bookEhcache", "headTitleInfo");
        jsonArray.sort(Comparator.comparing(obj -> ((JSONObject) obj).getInteger("chapterNum")));

        JSONObject jo =bookChapterDao.getBookInfo("bookId");

        for (int i = 0; i <jsonArray.size() ; i++) {
            JSONObject s = (JSONObject) jsonArray.get(i);
            if(jo.containsKey(s.getString("chapterName"))){
                BookChapter bi = (BookChapter) jo.get(s.getString("chapterNam   e"));
                s.put("chapterId",bi.getChapterId());
            }
        }

   //     bookChapterDao.saveBookChapter(jsonArray);
        JSONObject rs = new JSONObject();

        rs.put("title",headTitleInfo);
        rs.put("zjList",jsonArray);


        return rs;
    }

    @Override
    public JSONObject queryReadBook(JSONObject param) {
        String chapterId = param.getString("chapterId");
        String ruleId = param.getString("bookRule");
        Request request = new Request();
        JSONObject chapterInfo = param;
        BookRule bookRule = bookDao.findById(ruleId).orElse(null);
        request.putExtra("book","context");
        request.putExtra("state","update");
        request.putExtra("bookRule", JSONObject.parse(JSONObject.toJSONString(bookRule)));
        request.putExtra("bookInfo", chapterInfo);
        request.setUrl(param.getString("chapterSource"));
        request.setCharset("gbk");
        BookMagicCommon.bookSearch(request);

        //缓存取数据
       JSONObject rs = (JSONObject) EhcacheUtil.getInstance().get("bookEhcache","chapter");

        //移除缓存
        EhcacheUtil.getInstance().remove("bookEhcache", "chapter");
        BookChapter bt = rs.toJavaObject(BookChapter.class);
        if(StringUtils.isNotBlank(chapterId)){
            BookChapter bookChapter = bookChapterDao.findById(chapterId).orElse(null);
            if(bookChapter!=null)
                bookChapterDao.saveOrUpdateByNotNullProperties(bt);
        }

        return rs;
    }

    @Override
    public String downloadBook(String param) throws Exception {
        JSONObject p = JSONObject.parseObject(param);

        BookRule bookRule = bookDao.findById(p.getString("bookRuleSource")).orElse(null);
        Request request = new Request();
        request.putExtra("book","downfile");
        request.putExtra("state","downfile");
        request.putExtra("bookRule", JSONObject.parse(JSONObject.toJSONString(bookRule)));
        request.putExtra("bookListInfo", p);
        request.putExtra("type","0");
        request.setUrl(p.getString("ruleSearchNoteUrl"));
        request.setCharset("gbk");
        BookMagicCommon.bookSearch(request);

        //缓存取数据
        JSONArray jsonArray= JSONArray.parseArray(JSONObject.toJSONString(EhcacheUtil.getInstance().get("bookEhcache","downFile")));
        //移除缓存
        EhcacheUtil.getInstance().remove("bookEhcache", "downFile");
        jsonArray.sort(Comparator.comparing(obj -> ((JSONObject) obj).getInteger("chapterNum")));
        String sysPath = System.getProperty("user.dir");
        String tempPath = "/temp/bookDowntemmp/";
        System.out.println("系统路径"+System.getProperty("user.dir"));

        File file = new File(sysPath+tempPath);
        if(!file.exists()){
            file.mkdirs();
        }
        String titleName = p.getString("ruleSearchName")+".txt";
        File writename = new File(sysPath+tempPath+titleName);
        writename.createNewFile();
        BufferedWriter out = new BufferedWriter(new FileWriter(writename));
        StringBuffer str = new StringBuffer();
        for (int i = 0; i < jsonArray.size(); i++) {
            str.setLength(0);
            JSONObject da = jsonArray.getJSONObject(i);
            str.append(da.getString("chapterName"));
            out.write(str.toString());
            out.write("\r\n");
            //多增加 一空行
            out.write("\r\n");
            str.setLength(0);
            str.append(da.getString("chapterContext").replaceAll("    ","\r"));
            out.write(str.toString());
            out.write("\r\n");
            //多增加 一空行
            out.write("\r\n");
        }
        out.close();
//        Long b = System.currentTimeMillis();
//        System.out.println("耗时长:"+(b-a)/1000);

        System.out.println("rs>>>>>>>>>>>>>"+sysPath+tempPath+titleName);


        return sysPath+tempPath+titleName;
    }

    @Override
    public JSONArray queryBookList(JSONObject param) {
        JSONArray rs = dao.queryBookList(param);
        return rs;
    }

    /**
     * type 0 网站首页  1:明细初始化     2 文档阅读页
     * @return
     */
    @Override
    public JSONObject initData() throws Exception {
        BookRule bookRule = bookDao.findById("").orElse(null);
        JSONObject jo = new JSONObject();


/*        StringBuffer sql = new StringBuffer();
        sql.append(" select book_id,book_source,book_last_chapter_url from book_list_info");
        List<Map<String,Object>> mplist = dao.queryListBySql(sql.toString());
        List<String> sqlLsit  =new ArrayList<>() ;
        StringBuffer sqlStr = new StringBuffer();
        for(Map<String,Object> map:mplist){
            sqlStr.setLength(0);
            String str =map.get("book_last_chapter_url").toString();
            String st = str.substring(str.lastIndexOf("/"));
            sqlStr.append(" update book_list_info set book_last_chapter_url='"+map.get("book_source").toString()+str.substring(str.lastIndexOf("/"))+"'  ");
            sqlStr.append(" where book_id='"+map.get("book_id")+"'");
            sqlLsit.add(sqlStr.toString());
        }
        dao.doExecuteBatch(sqlLsit);*/

        JSONObject ds = dao.querybookSource("e821e7e079dbe61aaf03ca008b5cetws");

/*        select  s.book_id ,s.book_name,ts from (

                select  substring(book_source, 23)ts,book_id,book_name from book_list_info ) s

        where s.ts BETWEEN 18000 and 20000
        order by CONVERT(ts,UNSIGNED)*/
        //多线程调用下载
        ExecutorService exec = Executors.newFixedThreadPool(30);//工头

        for (int i = 50000; i < 114000; i++) {
            Request request = new Request();
            request.putExtra("rule",bookRule);
             if(!ds.containsKey(String.valueOf(i))){
                request.putExtra("type","1");
                request.setUrl("http://147xs.org/book/"+i);
             initDataCommon.initData(request);
            exec.submit(new initDataTask(request,"1"));
              }
        }
        exec.shutdown();
        exec.awaitTermination(1, TimeUnit.HOURS);
        JSONArray bfo = new JSONArray();
        //JSONArray cfo = new JSONArray();
        JSONObject bookInfo = (JSONObject) EhcacheUtil.getInstance().get("bookEhcache","bookInfo");
        EhcacheUtil.getInstance().remove("bookEhcache", "bookInfo");
        ExecutorService ex = Executors.newFixedThreadPool(50);//工头
        for (Map.Entry<String, Object> entries  : bookInfo.entrySet()) {
            JSONObject info = (JSONObject) entries.getValue();
            bfo.add(info.getJSONObject("bookInfo"));
            //cfo.addAll(info.getJSONArray("chapterInfo"));
            JSONObject book = info.getJSONObject("bookInfo");
            JSONArray chapter = info.getJSONArray("chapterInfo");
            ex.submit(new saveSearchTask(chapter,"BookChapter"));
        }
        ex.submit(new saveSearchTask(bfo,"BookListInfo"));



/*        JSONObject chapterInfo = (JSONObject) EhcacheUtil.getInstance().get("bookEhcache","chapterInfo");
        JSONObject rs = (JSONObject) EhcacheUtil.getInstance().get("bookEhcache","bookInfo");

        EhcacheUtil.getInstance().remove("bookEhcache", "chapterInfo");
        EhcacheUtil.getInstance().remove("bookEhcache", "bookInfo");
        JSONArray bookInfo = new JSONArray();

        for (Map.Entry<String, Object> entries  : rs.entrySet()) {
                JSONObject j = (JSONObject) entries.getValue();
                  bookInfo.add(j);
            }
        JSONArray cinfo = new JSONArray();
        for (Map.Entry<String, Object> entries  : chapterInfo.entrySet()) {
            JSONObject j = (JSONObject) entries.getValue();
            for (Map.Entry<String, Object> cj  : j.entrySet()) {
                cinfo.add(cj.getValue());
            }
        }
      //  List< BookListInfo> bli = bookInfo.toJavaList(BookListInfo.class);
        exec.submit(new saveSearchTask(bookInfo,"BookListInfo"));
        for (int i = 0; i < cinfo.size(); i++) {
           JSONArray r = (JSONArray) cinfo.get(i);
            //List< BookChapter> cli = r.toJavaList(BookChapter.class);
            exec.submit(new saveSearchTask(r ,"BookChapter"));
        }*/

        //  System.out.println(bli.size());

        //多线程下调用保存 不占查询时间
/*
        String type = "search";
        ExecutorService exec = Executors.newCachedThreadPool();//工头
        exec.submit(new saveSearchTask(jsonArray,type));
*/

        return null;
    }
    @Autowired
    private RedisValUtil redisValUtil;
    @Autowired
    private RedisListUtil redisListUtil;
    public JSONObject updateChapter(JSONObject jo )  {
        String range="100000";
        int thread =20;

        if(jo.isEmpty()){
        }else {
            StringBuffer sql = new StringBuffer();
/*            sql.append(" from BookListInfo ");
            List<BookListInfo> booklist = dao.findAll();
            redisValUtil.set("bookListInfo",booklist);*/
            sql.setLength(0);
            sql.append(" select  chapter_id chapterId,bc.book_id bookId,chapter_source chapterSource,chapter_num chapterNum,chapter_name chapterName,chapter_context chapterContext from book_list_info bli");
            sql.append("  left join book_chapter bc on bli.book_id=bc.book_id  ");
            sql.append(" where   CONVERT (int,REPLACE(bli.book_source,'http://147xs.org/book/' ,'')  ) BETWEEN 0 and 5000 ");
            List<Map<String, Object>> mapList = bookChapterDao.queryListBySql(sql.toString());
            JSONObject bookChapter = getBookChapter(mapList);
         //   List<BookChapter> bli = JSONArray.parseArray(JSON.toJSONString(mapList)).toJavaList(BookChapter.class);
            for (Map.Entry<String, Object> entry : bookChapter.entrySet()) {

                redisValUtil.set(1,entry.getKey(), entry.getValue());
            }

            return null;
        }


        StringBuffer sql = new StringBuffer();
        sql.append(" select  top "+range+" bc.chapter_id, chapter_source from book_list_info bli left join book_chapter bc on  bli.book_id=bc.book_id ");
        sql.append(" where 1=1 and  bc.chapter_context='' order by book_source ");

        List<Map<String,Object>> mapList = dao.queryListBySql(sql.toString());

        ExecutorService exec = Executors.newFixedThreadPool(thread);//工头

        for(Map<String,Object> map:mapList){
            JSONObject ci = new JSONObject();
            Request request = new Request();
           ci.put("chapterId",map.get("chapter_id"));
            request.putExtra("chapterInfo",ci);
            request.putExtra("type","2");
            request.setUrl(map.get("chapter_source").toString());
            exec.submit(new initDataTask(request,"2"));
        }

        try {
            exec.shutdown();
            exec.awaitTermination(1, TimeUnit.HOURS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
/*        JSONObject chapterInfo = (JSONObject) EhcacheUtil.getInstance().get("bookEhcache","chapterInfo");
        System.out.println(chapterInfo);
        EhcacheUtil.getInstance().remove("bookEhcache", "chapterInfo");*/

        return null;
    }



    private JSONObject getBookChapter(List<Map<String, Object>> mapList) {
        JSONObject rs =  new JSONObject();
        for (Map<String,Object> mp: mapList) {
            if (rs.containsKey(mp.get("bookId"))){
                rs.getJSONArray(mp.get("bookId").toString()).add(new JSONObject(mp));
            }
            else{
                JSONArray ja = new JSONArray();
                ja.add(new JSONObject(mp));
                rs.put(mp.get("bookId").toString(), ja);
            }

        }
        return  rs;
    }


    /**
     * 通用解析处理
     * @ type：0 单个解析 1 指定顺序 3 单书下载
     * 自定义规则解析 使用 List<String> 解析顺序
     * 多线程解析 加速效率
     */
    public JSONObject jxRulePage(JSONObject param) {
        int thread  = 1;
        if (param.containsKey("thread"))
            thread = param.getInteger("thread");
        try {
            final long start = System.currentTimeMillis();
                ExecutorService exec = Executors.newFixedThreadPool(thread);// 线程数
                exec.submit(new JXPageRuleThread(param,"1"));

                exec.shutdown();
            exec.awaitTermination(1, TimeUnit.HOURS);
            final long end = System.currentTimeMillis();
            System.out.println("线程执行时间："+(end-start)/1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }
    @Override
    public JSONArray SearchPage(JSONObject param) {
        List<String> num = new ArrayList<>();
        num.add("bookSearch");
        //取出规则
        StringBuffer sql = new StringBuffer();
        sql.append("select rule_id ruleId ,rule_name ruleName ,root_source rootSource,root_search rootSearch,root_type rootType,rule_book_list ruleBookList,");
        sql.append(" rule_chapter_list ruleChapterList, rule_set ruleSet ");
        sql.append(" from book_rule_set where is_stop = '0' ");
        if(param.containsKey("ruleId"))
            sql.append(" and rule_id = '").append(param.getString("ruleId")).append("'");

        JSONArray ds = dao.queryJSONArrayBySql(sql.toString());

        JSONObject req = new JSONObject();
        JSONObject bs=null;
        String id = "";
        if (ds.size()>0){
            for (int i = 0; i < ds.size(); i++) {
                JSONObject jo = ds.getJSONObject(i);
                JSONObject reset = JSONObject.parseObject(jo.getString("ruleSet"));
                param.put("ruleId",jo.getString("ruleId"));
                List<String> set = new ArrayList<>();
                if(param.containsKey("search"))
                    req.put("url",jo.getString("rootSearch")+param.getString("search"));
                    set.add("bookSearch");
                    JSONObject cond = new JSONObject();
                    cond.put("key",jo.getString("ruleId"));
                    cond.put("keyName",jo.getString("ruleName"));
                    cond.put("num",set);
                    req.put("ruleSet",reset);
                    req.put("cond",cond);
                    req.put("thread",1);
                    req.put("param",param);//附加参数
                    jxRulePage(req);
                    id=jo.getString("ruleId");
                 bs = (JSONObject) EhcacheUtil.getInstance().get("bookEhcache",jo.getString("ruleId"));
            }
        }
        JSONArray rs =  bs.getJSONArray("bookSearch");
        EhcacheUtil.getInstance().remove("bookEhcache",id);
        return rs;
    }

    /**
     * 以本书为单位进行缓存
     * bookId 为key 内容分为 书明细 章节明细
     * @param param
     * @return
     */
    @Override
    public JSONObject getBookInfo(JSONObject param) {
        JSONObject bs= new JSONObject();
        JSONObject br = dao.queryJSONObjectBySql(BookCommutils.bookRuleStr(param));
        String bookId = BookCommutils.MD5(param.getString("bookUrl"));
        param.put("type","bookChapterList");
        JSONObject req = new JSONObject();
        JSONObject reset = JSONObject.parseObject(br.getString("ruleSet"));
        String ruleId = param.getString("ruleId") ;
        List<String> set = new ArrayList<>();
        set.add("bookChapterList");
        JSONObject cond = new JSONObject();
        cond.put("key",bookId);
        cond.put("num",set);
        req.put("ruleSet",reset);
        req.put("cond",cond);
        req.put("thread",1);
        req.put("param",param);//附加参数
        req.put("url",param.getString("bookUrl"));
        jxRulePage(req);
        bs = (JSONObject) EhcacheUtil.getInstance().get("bookEhcache",bookId);
        JSONObject bf = bs.getJSONObject("chapterInfo");
        JSONArray ch = new JSONArray();

        for (Map.Entry entry : bf.entrySet()) {
            ch.add(entry.getValue());
        }
        ch.sort(Comparator.comparing(obj -> ((JSONObject) obj).getInteger("num")));
        bs.put("chapterInfo",ch);

        //调用多线程处理 保存点击查询的数据 数据明细以及章节 后对章节进行内容更新 返回筛选知道所有章节更新完毕
/*        ExecutorService exec = Executors.newFixedThreadPool(1);// 线程数
        exec.submit(new saveThead(br,bs));*/
        return bs;
    }

    /**
     * 章节阅读
     * 必须包含
     * Ruleid 来源规则  bookId 书籍Id  chapterUrl  章节ID
     * key值重新定义 需要传入key值取值  不再解析中取值
     * 鉴于上一章 下一章只改变了 当前连接的url 其余信息相同所以需要根据当前url 重新生成param 参数
     * @param param
     * @return
     */
    @Override
    public JSONObject readBook(JSONObject param) {
        if (param.containsKey("type")){
            param.put("chapterId", BookCommutils.MD5(param.getString("chapterUrl")));
            if(param.getString("type").equals("up")){
                //下页 搜索页进来的没有num属性 可不赋次属性
                if (param.containsKey("num"))
                     param.put("num",param.getInteger("num")-1);
            }else{
                //下页 搜索页进来的没有num属性 可不赋次属性
                if (param.containsKey("num"))
                     param.put("num",param.getInteger("num")+1);
            }
        }
        String chapterId = "";
        if(param.containsKey("chapterId"))
            chapterId = param.getString("chapterId");
        else
            chapterId = BookCommutils.MD5(param.getString("chapterUrl"));
        //先判断数据库中或缓存中是否含有此文本内容 如果不含者从网上下载
        JSONObject bs= new JSONObject();
        JSONObject br = dao.queryJSONObjectBySql(BookCommutils.bookRuleStr(param));
        JSONObject req = new JSONObject();
        JSONObject reset = JSONObject.parseObject(br.getString("ruleSet"));
        String ruleId = param.getString("ruleId") ;
        List<String> set = new ArrayList<>();
        param.put("type","chapterContext");
        set.add("chapterContext");
        JSONObject cond = new JSONObject();
        cond.put("key",chapterId);
        cond.put("num",set);
        req.put("ruleSet",reset);
        req.put("cond",cond);
        req.put("thread",1);
        req.put("param",param);//附加参数
        req.put("url",param.getString("chapterUrl"));

        jxRulePage(req);
      //  RuleJXData.RuleJXDataPage(req);
        bs = (JSONObject) EhcacheUtil.getInstance().get("bookEhcache",chapterId);
        return bs;
    }
    /**
     * 下载小说
     * @param param
     * @return
     */
    @Override
    public String downloadFile(JSONObject param) throws Exception {

        String bookId = param.getString("bookId");
        //获取当前章节缓存
        JSONObject ns =   (JSONObject) EhcacheUtil.getInstance().get("bookEhcache",bookId);
        JSONArray chapterInfo = ns.getJSONArray("chapterInfo");

        JSONObject br = dao.queryJSONObjectBySql(BookCommutils.bookRuleStr(param));
        JSONObject req = new JSONObject();
        JSONObject reset = JSONObject.parseObject(br.getString("ruleSet"));
        Long a= System.currentTimeMillis();

        ExecutorService exec = Executors.newFixedThreadPool(20);// 线程数

        for (int i = 0; i < chapterInfo.size(); i++) {
            JSONObject p = chapterInfo.getJSONObject(i);
            List<String> set = new ArrayList<>();
            set.add("downFile");
            JSONObject cond = new JSONObject();
            cond.put("key","downFile");
            cond.put("num",set);
            req.put("ruleSet",reset);
            req.put("cond",cond);
            //req.put("thread",10);
            req.put("param",p);//附加参数
            req.put("url",p.getString("chapterUrl"));
           // jxRulePage(req);
            exec.submit(new JXPageRuleThread(req,"1"));
        }
        exec.shutdown();
        exec.awaitTermination(1, TimeUnit.HOURS);

        //缓存取数据
        JSONArray jsonArray= JSONArray.parseArray(JSONObject.toJSONString(EhcacheUtil.getInstance().get("bookEhcache","downFile")));
        //移除缓存
      //  EhcacheUtil.getInstance().remove("bookEhcache", "downFile");
        jsonArray.sort(Comparator.comparing(obj -> ((JSONObject) obj).getInteger("num")));
        String sysPath = System.getProperty("user.dir");
        String tempPath = "/temp/bookDowntemmp/";
        System.out.println("系统路径"+System.getProperty("user.dir"));

        File file = new File(sysPath+tempPath);
        if(!file.exists()){
            file.mkdirs();
        }
        String titleName = param.getString("bookName")+".txt";
        File writename = new File(sysPath+tempPath+titleName);
        writename.createNewFile();
        BufferedWriter out = new BufferedWriter(new FileWriter(writename));
        StringBuffer str = new StringBuffer();
        for (int i = 0; i < jsonArray.size(); i++) {
            str.setLength(0);
            JSONObject da = jsonArray.getJSONObject(i);
            str.append(da.getString("chapterName"));
            out.write(str.toString());
            out.write("\r\n");
            //多增加 一空行
            out.write("\r\n");
            str.setLength(0);
            str.append(da.getString("context").replaceAll("    ","\r"));
            out.write(str.toString());
            out.write("\r\n");
            //多增加 一空行
            out.write("\r\n");
        }
        out.close();
        Long b = System.currentTimeMillis();
        System.out.println("耗时长:"+(b-a)/1000);
        return sysPath+tempPath+titleName;
    }




}
